#include <stdio.h>
#include <unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include <netinet/in.h>

#include<event2/event.h>
#include<event2/bufferevent.h>
#include<event2/listener.h>

//读回调
void read_cb(struct bufferevent* bev, void* arg)
{
    //读缓冲区数据
    char buf[1024] = {0};
    bufferevent_read(bev, buf, sizeof(buf));
    printf("current buf is %s", buf);

    char* ptr = "123456\n";
    bufferevent_write(bev, ptr, strlen(ptr)+1);
    printf("read success write\n");
}
//写回调
void write_cb(struct bufferevent* bev, void* arg)
{
    printf("write callback\n");
}

void event_cb(struct bufferevent* bev, short event, void* arg)
{
    if (event & BEV_EVENT_EOF) {
        printf("BEV_EVENT_EOF\n");
    } else if (event & BEV_EVENT_ERROR) {
        printf("BEV_ERROR\n");
    }
    //释放资源
    bufferevent_free(bev);
}


void listen_cb(struct evconnlister* listener,
        short fd, //evutil_sockaddr_t fd,
        struct sockaddr* addr,
        int len, void* ptr)
{
    //拿base
    struct event_base* base = (struct event_base*)ptr;

    //接收和发送数据交互
    //将fd封装为事件
    struct bufferevent* bev = NULL;
    bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    //给读写缓冲区设置回调函数
    bufferevent_setcb(bev, read_cb, write_cb, event_cb,NULL);
    //设置读缓冲区为可用的,默认写是可用的
    bufferevent_enable(bev, EV_READ);
}

int main()
{
    //创建事件处理框架
    struct event_base* base = event_base_new();
    //准备sockaddr
    struct sockaddr_in serv;
    memset(&serv, 0, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_port = htons(8765);
    serv.sin_addr.s_addr = htonl(INADDR_ANY);
    //创建监听套接字
    //绑定
    //监听
    //等待并链接
    struct evconnlistener* listen = NULL;
    //有连接时，licten cb就会被调用
    listen = evconnlistener_new_bind(base, listen_cb, base,
            LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
            -1, (struct sockaddr*)&serv, sizeof(serv));

    //进入到事件循环
    event_base_dispatch(base);

    //释放资源
    evconnlistener_free(listen);
    event_base_free(base);
    return 0;
}